#include "libBignum/include/Bignum.hpp"//使用自定义的头文件，写出头文件的路径

int main()
{
    BigNum a, b;              //使用类
    std::string num_a, num_b; //定义两个字符串

    std::cin >> num_a >> num_b;
    a.setNum(num_a);    // . 使用成员函数，这里是录入字符串数据到类里面
    b.setNum(num_b);

    // a.print();
    // b.print();

    BigNum c;
    c = a + b; // + 是重载运算符，实现大数计算的核心

    c.print();

    return 0;
}
//以下是头文件内容
#include <iostream>
//头文件的作用主要是声明，而非定义或计算
class BigNum//定义类
{
public:
    BigNum() {}    //默认构造函数,作用是初始化变量
    BigNum(std::string num);  //接受一个std::string类型的参数来初始化大数

    void setNum(std::string num); 
    void print();
    void pop(char num);

    BigNum operator=(BigNum num); //重载 = 运算符
    friend BigNum operator+(BigNum bignum_a, BigNum bignum_b); //重载 + 运算符

private:
    std::string m_num; //定义内部string变量m_num
};

//下面是各个函数定义的环节
#include "libBignum/include/Bignum.hpp"

BigNum::BigNum(std::string num) //classname::functionname表明成员函数
{
    setNum(num); //如果程序中编写成了  a.BigNum(num_a);一样完成输入
}

void BigNum::setNum(std::string num)
{
    m_num = num;      //输入端口
}

void BigNum::print()
{
    std::cout << m_num << std::endl;  //输出端口
}

void BigNum::pop(char num)
{ //在原来字符串的基础上，向前录入一个新字符
    m_num = num + m_num; //在c++中，编译器可以认可这种操作（char+string），产生 ('num'"m_num")的组合，如果颠倒相加顺序，那么组合顺序也会相应颠倒
}
//输入 BigNum类的 bignum变量，
BigNum BigNum::operator=(BigNum bignum) 
{ 
    m_num = bignum.m_num;  //c=x,如果x是BigNum类的话，x中的m_num就会赋值到c的m_num当中 
}

BigNum operator+(BigNum bignum_a, BigNum bignum_b)
{ //核心，重载+运算符，注意输入的是字符串，所以进位需要特别实现
    BigNum result;    //定义rusult变量

    int max_length = std::max(bignum_a.m_num.length(), bignum_b.m_num.length());//找到其中较长的大数的长度
    //用两个循环，将大数前段缺少的地方位数用‘0’补齐
    for (int i = bignum_a.m_num.length(); i < max_length; i++)
    {
        bignum_a.pop('0');
    }
    for (int i = bignum_b.m_num.length(); i < max_length; i++)
    {
        bignum_b.pop('0');
    }

    int front = 0;
    for (int i = 0; i < max_length; i++) //对于每一个数位，遍历相加，进位情况
    {
        int a = bignum_a.m_num[bignum_a.m_num.length() - i - 1] - '0';//string是一种数组，所以用数组的形式查找相应数位的值，并转化为整型
        int b = bignum_b.m_num[bignum_b.m_num.length() - i - 1] - '0';//利用char的存储就是整型，从而完成char--int转化（这里-‘0’是必要的，依靠的是ascii的连续顺序）

        if (a + b + front > 9)
        {
            result.pop(a + b - 10 + front + '0'); //还是利用间隔，实现int--char转化，利用pop的性质完成result字符串的搭建
            front = 1;
        }
        else
        {
            result.pop(a + b + front + '0');
            front = 0;
        }
    }
    
    if (front == 1)
    {
        result.pop('1');
    }

    return result;
}
//下面是CMake
/*
首先应该清楚工程的文件结构和调用目的与关系：
.
├── build
├── CMakeLists.txt
├── libBignum
│   ├── CMakeLists.txt
│   ├── include
│   │   └── Bignum.hpp
│   └── src
│       └── Bignum.cpp
└── test.cpp
在 test.cpp中，我们使用了Bignum.hpp头文件，使用了Bignum.cpp里面的类，
Bignum.cpp里面同样使用了Bignum.hpp的声明，大概这样……
*/

//在Bignum.cpp里 使用 Bignum.hpp的头文件

include_directories(${PROJECT_SOURCE_DIR}) //向工程添加多个特定的头文件搜索路径
//${PROJECT_SOURCE_DIR}是一个CMake变量，它表示项目的根目录
get_property(include_dir DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
//啥意思？？彻底傻了：（
set(BIGNUM_INCLUDE ${include_dir} PARENT_SCOPE)
//PARENT_SCOPE关键字表示目标变量BIGNUM_INCLUDE能在父作用域（上一级）被使用

add_library(Bignum SHARED ./src/Bignum.cpp)
//生成库文件，类型是SHARED




cmake_minimum_required(VERSION 3.2)

project(Bignum)

set(CMAKE_CXX_STANDARD 14)

add_subdirectory(${PROJECT_SOURCE_DIR}/libBignum)
//向当前工程添加存放源文件的子目录
include_directories(${BIGNUM_INCLUDE})
//向工程添加多个特定的头文件搜索路
add_executable(BignumTest ${PROJECT_SOURCE_DIR}/test.cpp)

//cmake是真看不懂一点……